/**************************************************************************
	File		: upgrade.c
	Author		: TaoLei Zhang
	Date		: 2018-2-6
***************************************************************************/

/**************************************************************************
    								include
***************************************************************************/

#include "if.h"
#include "upgrade.h"
#include "Common.h"
/**************************************************************************
    								macro
***************************************************************************/
#define ACK_TIME_OUT			1000				/* t*1ms */
/**************************************************************************
    								typedef
***************************************************************************/

/**************************************************************************
    								variables
***************************************************************************/
volatile pthread_mutex_t SendPacketMutex;

McuMsg_t g_Msg_tx;
McuMsg_t g_Msg_rx;
volatile uint16_t g_ReqId;
volatile uint16_t g_McuReqState = MSG_Butt;
volatile uint16_t g_McuErrCode = DI_Ok;
/**************************************************************************
    								functions
***************************************************************************/
DI_RET_e SendPacket(DI_McuIfHandle hdl, McuMsgType_e msgType, uint8_t *data, uint16_t len) {
	DI_RET_e ret;
	McuIfCtx_t *pCtx = (McuIfCtx_t*)hdl;
	uint16_t timeCnt = 0;
	uint16_t wrlen;
	uint16_t packLen;

	if (g_McuReqState != MSG_Butt)
	{
		DebugPrint("is busy now %d", g_McuReqState);
		return DI_Busy;
	}
	pthread_mutex_lock(&SendPacketMutex);
	g_McuReqState = msgType;

	if (len > sizeof(g_Msg_tx.content.data)) {
		DebugPrint("data too large, len:%d", len);
		ret = DI_DataTooLarge;
		goto End;
	}
	if (0 == ++g_ReqId) {
		g_ReqId++;
	}
	MakeMcuMsg(&g_Msg_tx, data, len, DI_Ok, msgType, g_ReqId);
	packLen = g_Msg_tx.header.len + sizeof(McuMsgHeader_t);

	pthread_mutex_lock(&pCtx->mutex);
	wrlen = UartSend(pCtx, &g_Msg_tx, packLen);
	pthread_mutex_unlock(&pCtx->mutex);

	if (packLen != wrlen) {
		g_McuReqState = MSG_Butt;
		ret = DI_DeviceOperErr;
		goto End;
	}
	while(1) {
		if (g_McuReqState == MSG_Butt) {
			ret = g_McuErrCode;
			goto End;
		}

		if (timeCnt++ > ACK_TIME_OUT) {
			break;
		}
		Sleep(1);			//Ms
	}

	DebugPrint("mcu ack timeout!\n");
	g_McuReqState = MSG_Butt;
	ret = DI_DeviceAckTimeout;
End:
	pthread_mutex_unlock(&SendPacketMutex);
	return ret;
}

Bool SendBeginPacket(DI_McuIfHandle hdl, uint16_t reqId)
{
	DI_RET_e ret = SendPacket(hdl, MSG_UPGRADE_Begin, NULL, 0);
	if (ret == DI_DeviceOperErr)
		DebugPrint("Send begin packet error\n");
	if (ret == DI_DeviceAckTimeout)
		DebugPrint("SendBeginPacket timeout!\n");
	return ret == DI_Ok;
}

Bool SendDspBeginPacket(DI_McuIfHandle hdl, uint16_t reqId)
{
	DI_RET_e ret = SendPacket(hdl, MSG_DSP_TOPO_UpdateMode, NULL, 0);
	if (ret == DI_DeviceOperErr)
		DebugPrint("Send dsp begin packet error\n");
	if (ret == DI_DeviceAckTimeout)
		DebugPrint("SendDspBeginPacket timeout!\n");
	return ret == DI_Ok;
}

Bool SendUserCode(DI_McuIfHandle hdl, uint8_t *data, uint16_t len, uint16_t reqId)
{
	DI_RET_e ret = SendPacket(hdl, MSG_UPGRADE_Data, data, len);
	if (ret == DI_DeviceOperErr)
		DebugPrint("Send data packet error\n");
	if (ret == DI_DeviceAckTimeout)
		DebugPrint("SendUserCode timeout!\n");
	return ret == DI_Ok;
}

Bool SendEndPacket(DI_McuIfHandle hdl, uint16_t reqId)
{
	DI_RET_e ret = SendPacket(hdl, MSG_UPGRADE_End, NULL, 0);
	if (ret == DI_DeviceOperErr)
		DebugPrint("Send end packet error\n");
	if (ret == DI_DeviceAckTimeout)
		DebugPrint("SendEndPacket timeout!\n");
	return ret == DI_Ok;
}

Bool SendRebootMsg(DI_McuIfHandle hdl, uint16_t reqId)
{
	DI_RET_e ret = SendPacket(hdl, MSG_MCU_Reboot, NULL, 0);
	if (ret == DI_DeviceOperErr)
		DebugPrint("Send reboot packet error\n");
	if (ret == DI_DeviceAckTimeout)
		DebugPrint("sendRebootMsg timeout!\n");
	return ret == DI_Ok;
}


